<script setup>
import { ref, onMounted, onUnmounted, nextTick, watch } from 'vue'
import { unit2 } from '../unit.js'

const props = defineProps({
    config: {
        type: Object,
        default: {list:[]}
    },
});

var swiper;

watch(() => props.config, (newVal, oldValue) => {
    nextTick(() => {
        swiper.init(props.config.autoplay, props.config.delay*1000);
    })
},{
    deep: true
})

const myCarousel = ref()

onMounted(() => {

    nextTick(() => {
        // 初始化轮播图
        swiper = new Carousel(myCarousel.value);
        // (是否自动播放，播放时间间隔)
        swiper.init(props.config.autoplay, props.config.delay*1000)
    })

});
onUnmounted(() => {
    swiper.destroy()
});


// 轮播图实例，常用基础功能。
// 更复杂场景可使用swiper.js等第三方插件

function Carousel(myCarousel) {
    var autoPlay = false;
    var interval = 3000;
    var currentIndex = 0;
    const carousel = myCarousel || document.getElementById('myCarousel');
    const inner = carousel.querySelector('.carousel-inner');
    var items = carousel.querySelectorAll('.carousel-item');
    var indicators = carousel.querySelectorAll('.carousel-indicators li');
    let timer;
    let _height;

    function updateCarousel() {
        _height && autoHeight()
        inner.style.transform = `translateX(-${currentIndex * 100}%)`;
        indicators.forEach(ind => ind.classList.remove('active'));
        indicators[currentIndex].classList.add('active');
    }

    function goToSlide(index) {
        currentIndex = index;
        updateCarousel();
    }

    // indicators.forEach((indicator, index) => {
    //     indicator.addEventListener('click', () => goToSlide(index));
    // });

    function nextSlide() {
        currentIndex = (currentIndex + 1) % items.length;
        updateCarousel();
    }

    function prevSlide() {
        currentIndex = (currentIndex - 1 + items.length) % items.length;
        updateCarousel();
    }

    function mouseenter() {
        if (autoPlay) clearInterval(timer);
    }
    function mouseleave() {
        if (autoPlay) {
            timer && clearInterval(timer)
            timer = setInterval(nextSlide, interval);
        }
    }
    carousel.addEventListener('mouseenter', mouseenter);

    carousel.addEventListener('mouseleave', mouseleave);


    var startX = 0;
    // Common gesture start event handler
    function gestureStart(event) {
        startX = event.type.includes('touch') ? event.touches[0].clientX : event.clientX;
    }

    // Common gesture end event handler
    function gestureEnd(event) {
        if (!startX) return;

        const endX = event.type.includes('touch') ? event.changedTouches[0].clientX : event.clientX;
        const diffX = endX - startX;

        if (diffX > 50) {
            prevSlide();
        } else if (diffX < -50) {
            nextSlide();
        }

        startX = 0;
        timer && clearInterval(timer);
    }

    // Add event listeners for both touch and mouse events
    carousel.addEventListener('touchstart', gestureStart);
    carousel.addEventListener('touchend', gestureEnd);
    carousel.addEventListener('mousedown', gestureStart);
    carousel.addEventListener('mouseup', gestureEnd);

    function autoHeight() {
        carousel.style.height = `${items[currentIndex].querySelector('img').clientHeight}px`;
    }

    return {
        init: function (_autoPlay, _interval) {
            items = carousel.querySelectorAll('.carousel-item');
            indicators = carousel.querySelectorAll('.carousel-indicators li');
            indicators.forEach((indicator, index) => {
                if (!indicator.hasAttribute('data-click')) {
                    indicator.addEventListener('click', () => goToSlide(index));
                    indicator.setAttribute('data-click', true);
                }
            });
            if (carousel.style.height === 'auto') {
                _height = 'auto';
                const img = items[currentIndex].querySelector('img');
                if(img.complete){
                    updateCarousel()
                }else{
                    img.onload = function () {
                        updateCarousel()
                    }
                }
            } else {
                _height = false;
                updateCarousel()
            }
            autoPlay = _autoPlay;
            interval = _interval||interval||3000;
            if (autoPlay) {
                timer && clearInterval(timer)
                timer = setInterval(nextSlide, interval);
            }else{
                clearInterval(timer)
            }
        },
        destroy: function () {
            timer && clearInterval(timer);
            carousel.removeEventListener('touchstart', gestureStart);
            carousel.removeEventListener('touchend', gestureEnd);
            carousel.removeEventListener('mousedown', gestureStart);
            carousel.removeEventListener('mouseup', gestureEnd);
            carousel.removeEventListener('mouseleave', mouseenter);
            carousel.removeEventListener('mouseenter', mouseleave);
        },
        goto: function (index) {
            goToSlide(index);
        },
        next: function () {
            nextSlide();
        },
        prev: function () {
            prevSlide();
        },
        play: function (_interval) {
            timer && clearInterval(timer)
            timer = setInterval(nextSlide, _interval||interval);
        },
        stop: function () {
            clearInterval(timer);
        }
    }

}


</script>

<template>

    <div class="carousel" id="myCarousel" ref="myCarousel" :style="{
        width: unit2(config?.width, config?.width_unit),
        height: unit2(config?.height, config?.height_unit),
        borderRadius: unit2(config?.borderRadius),
        marginBottom: unit2(config?.marginBottom),
    }">
        <div class="carousel-inner">
            <div class="carousel-item" v-for="(item, index) in config?.list">
                <img :class="{ objcover: config?.height_unit != 'auto' }" :src="item.url" draggable="false">
            </div>
        </div>
        <ol class="carousel-indicators">
            <li v-for="item in config?.list"></li>
        </ol>
    </div>

</template>

<style scoped>
.carousel {
    position: relative;
    overflow: hidden;
    width: 100%;
    margin: 0 auto;
}

.carousel-inner {
    display: flex;
    transition: transform 0.5s ease-in-out;
    height: 100%;
}

.carousel-item {
    min-width: 100%;
    height: 100%;
    overflow: hidden;
}

.carousel-item img {
    width: 100%;
    -webkit-user-drag: none;
}

.carousel-indicators {
    position: absolute;
    bottom: 8px;
    left: 50%;
    transform: translateX(-50%);
    list-style: none;
    padding: 0;
}

.carousel-indicators li {
    display: inline-block;
    margin: 0 1px;
    width: 16px;
    height: 16px;
    line-height: 12px;
    text-align: center;
    cursor: pointer;
}
.carousel-indicators li::after{
    display: inline-block;
    vertical-align: middle;
    content: '';
    width: 6px;
    height: 6px;
    background-color: #fff;
    border-radius: 50%;
    opacity: 0.5;
    box-shadow: rgba(0, 0, 0, 0.3) 0px 2px 5px;
}

.carousel-indicators .active::after {
    background-color: deepskyblue; opacity: 1;
}

.objcover{width: 100%;height: 100%;object-fit: cover;}
</style>